package main

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -lm
#include <stdlib.h>
#include <stdint.h>

// 纠错级别枚举
typedef enum {
    QR_EC_LEVEL_L = 0,  // 7%纠错
    QR_EC_LEVEL_M = 1,  // 15%纠错
    QR_EC_LEVEL_Q = 2,  // 25%纠错
    QR_EC_LEVEL_H = 3   // 30%纠错
} QRErrorCorrectionLevel;

// 错误码
typedef enum {
    QR_SUCCESS = 0,
    QR_ERROR_INVALID_PARAM = 1,
    QR_ERROR_CREATE_FAILED = 2,
    QR_ERROR_FILE_OPEN = 3,
    QR_ERROR_FILE_WRITE = 4,
    QR_ERROR_UNSUPPORTED_FORMAT = 5
} QRError;

// 仅保留PNG和JPG格式
typedef enum {
    QR_FORMAT_PNG = 0,
    QR_FORMAT_JPG = 1
} QRFormat;

// QR码对象结构体
typedef struct {
    void* qr_obj;       // Go的QRCode对象指针
    int module_count;   // 模块数
    int module_size;    // 每个模块的像素大小
    int border;         // 边框模块数
} QRCode;
*/
import "C"
import (
	"image"
	"image/color"
	"image/jpeg"
	"image/png"
	"os"
	"unsafe"

	"github.com/mdp/qrterminal/v3"
	"github.com/skip2/go-qrcode"
)

// 转换C的纠错级别到Go库类型
func toGoECLevel(ecl C.QRErrorCorrectionLevel) qrcode.RecoveryLevel {
	switch ecl {
	case C.QR_EC_LEVEL_M:
		return qrcode.Medium
	case C.QR_EC_LEVEL_Q:
		return qrcode.High
	case C.QR_EC_LEVEL_H:
		return qrcode.Highest
	default:
		return qrcode.Low
	}
}

//export qr_create
func qr_create(data *C.char, version C.int, ecl C.QRErrorCorrectionLevel, border C.int, module_size C.int) *C.QRCode {
	if data == nil || module_size <= 0 || border < 0 {
		return nil
	}

	goData := C.GoString(data)
	qr, err := qrcode.New(goData, toGoECLevel(ecl))
	if err != nil {
		return nil
	}

	// 修复：使用Bitmap()方法获取尺寸，而非直接访问Size字段
	bitmap := qr.Bitmap()
	moduleCount := len(bitmap)
	if moduleCount == 0 {
		return nil
	}

	cQR := (*C.QRCode)(C.malloc(C.sizeof_QRCode))
	cQR.qr_obj = unsafe.Pointer(qr)
	cQR.module_count = C.int(moduleCount)
	cQR.module_size = module_size
	cQR.border = border

	return cQR
}

//export qr_render_to_terminal
func qr_render_to_terminal(qr *C.QRCode) C.QRError {
	if qr == nil {
		return C.QR_ERROR_INVALID_PARAM
	}

	goQR := (*qrcode.QRCode)(qr.qr_obj)
	config := qrterminal.Config{
		Level:     qrterminal.M,
		Writer:    os.Stdout,
		BlackChar: "█",
		WhiteChar: " ",
		QuietZone: int(qr.border),
	}
	qrterminal.GenerateWithConfig(goQR.Content, config)

	return C.QR_SUCCESS
}

//export qr_save_to_file
func qr_save_to_file(qr *C.QRCode, filename *C.char, format C.QRFormat) C.QRError {
	if qr == nil || filename == nil {
		return C.QR_ERROR_INVALID_PARAM
	}

	goFilename := C.GoString(filename)
	goQR := (*qrcode.QRCode)(qr.qr_obj)
	totalSize := int(qr.module_count + 2*qr.border) * int(qr.module_size)
	imgRect := image.Rect(0, 0, totalSize, totalSize)
	rgba := image.NewRGBA(imgRect)

	black := color.RGBA{0, 0, 0, 255}
	white := color.RGBA{255, 255, 255, 255}
	bitmap := goQR.Bitmap()
	moduleCount := int(qr.module_count)
	border := int(qr.border)
	moduleSize := int(qr.module_size)

	for y := 0; y < totalSize; y++ {
		for x := 0; x < totalSize; x++ {
			moduleX := (x / moduleSize) - border
			moduleY := (y / moduleSize) - border

			var c color.RGBA
			if moduleX >= 0 && moduleX < moduleCount && moduleY >= 0 && moduleY < moduleCount && bitmap[moduleY][moduleX] {
				c = black
			} else {
				c = white
			}
			rgba.Set(x, y, c)
		}
	}

	file, err := os.Create(goFilename)
	if err != nil {
		return C.QR_ERROR_FILE_OPEN
	}
	defer file.Close()

	// 仅保留PNG和JPG格式
	switch format {
	case C.QR_FORMAT_PNG:
		err = png.Encode(file, rgba)
	case C.QR_FORMAT_JPG:
		err = jpeg.Encode(file, rgba, &jpeg.Options{Quality: 90})
	default:
		return C.QR_ERROR_UNSUPPORTED_FORMAT
	}

	if err != nil {
		return C.QR_ERROR_FILE_WRITE
	}
	return C.QR_SUCCESS
}

//export qr_get_width
func qr_get_width(qr *C.QRCode) C.int {
	if qr == nil {
		return 0
	}
	return C.int((qr.module_count + 2*qr.border) * qr.module_size)
}

//export qr_get_height
func qr_get_height(qr *C.QRCode) C.int {
	return qr_get_width(qr)
}

//export qr_destroy
func qr_destroy(qr *C.QRCode) {
	if qr != nil {
		C.free(unsafe.Pointer(qr))
	}
}

func main() {}